/**
 * @desc 函数防抖
 * @param func 目标函数
 * @param wait 延迟执行毫秒数
 * @param immediate true - 立即执行， false - 延迟执行
 */
export function debounce(func, wait, immediate) {
  let timer;
  return function () {
    let context = this,
      args = arguments;
    if (timer) clearTimeout(timer);
    if (immediate) {
      let callNow = !timer;
      timer = setTimeout(() => {
        timer = null;
      }, wait);
      if (callNow) func.apply(context, args);
    } else {
      timer = setTimeout(() => {
        func.apply(context, args);
      }, wait);
    }
  };
}

/**
 * 深拷贝
 * @param {*} obj
 */

export function deepClone(obj) {
  let result = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      if (typeof obj[key] === "object") {
        result[key] = deepClone(obj[key]); //递归复制
      } else {
        result[key] = obj[key];
      }
    }
  }
  return result;
}

/**
 * 延迟加载方法
 * @param {Function} fn
 * @param {number} time
 */
export function submitTimeOut(fn, time) {
  setTimeout(function () {
    fn();
  }, time);
}

/**
 * 函数节流
 * @param fn
 * @param wait
 * @param isImmediate
 * @returns {Function}
 */
export function throttle(fn, wait = 500, isImmediate = false) {
  let flag = true;
  let timer = null;
  if (isImmediate) {
    return function () {
      if (flag) {
        fn.apply(this, arguments);
        flag = false;
        timer = setTimeout(() => {
          flag = true;
        }, wait);
      }
    };
  }
  return function () {
    if (flag) {
      flag = false;
      let timer = setTimeout((...rest) => {
        fn.apply(this, rest);
        flag = true;
      }, wait);
    }
  };
}

/**
 * blob转base64
 * @param blob
 * @param cb
 */
export function blobToBase64(blob, cb) {
  let reader = new FileReader();
  reader.onload = function (evt) {
    const base64 = evt.target.result;
    cb(base64);
  };
  reader.readAsDataURL(blob);
}

/**
 * 返回其数据类型
 * @param para
 * @returns {string}
 * 结果 [object Undefined || Null || Object || Number || Array ||　Function || String]
 */
export function variateType(para) {
  return Object.prototype.toString.call(para);
}

/**
 * @desc 深拷贝，支持常见类型
 * @param {Any} values
 * @return {Any}
 */
export function deepClone(values) {
  var copy;

  // Handle the 3 simple types, and null or undefined
  if (null == values || "object" != typeof values) return values;

  // Handle Date
  if (values instanceof Date) {
    copy = new Date();
    copy.setTime(values.getTime());
    return copy;
  }

  // Handle Array
  if (values instanceof Array) {
    copy = [];
    for (var i = 0, len = values.length; i < len; i++) {
      copy[i] = deepClone(values[i]);
    }
    return copy;
  }

  // Handle Object
  if (values instanceof Object) {
    copy = {};
    for (var attr in values) {
      if (values.hasOwnProperty(attr)) copy[attr] = deepClone(values[attr]);
    }
    return copy;
  }

  throw new Error("Unable to copy values! Its type isn't supported.");
}

/**
 * @desc   判断`obj`是否为空
 * @param  {Object} obj
 * @return {Boolean}
 */
export function isEmptyObject(obj) {
  if (!obj || typeof obj !== "object" || Array.isArray(obj)) return false;
  return !Object.keys(obj).length;
}
